home *** CD-ROM | disk | FTP | other *** search
- program BoxRot;
-
- {PUBLIC DOMAIN 1993 Peter M. Gruhn
-
- Program draws a box on screen. Allows user to rotate the box around
- the three primary axes. Viewing transform is simple ignore z.
-
- I used _Computer_Graphics:_Principles_and_Practice_, Foley et al
- ISBN 0-201-12110-7 as a reference
-
- RUNNING:
- Borland Pascal 7. Should run on any graphics device supported by BGI.
- If you have smaller than 280 resolution, change '+200' to something
- smaller and/or change 75 to something smaller.
-
- Since this machine is
- not really set up for doing DOS graphics, I hard coded my BGI path, so
- you have to find 'initgraph' and change the bgi path to something that
- works on your machine. Try ''.
-
- Okey dokey. This is kinda slow, and does a nice job of demonstrating the
- problems of repeatedly modifying the same data set. That is, the more and
- more you rotate the box, the more and more distorted it gets. This is
- because computers are not perfect at calculations, and all of those little
- errors add up quite quickly.
-
- It's because of that that I used reals, not reals. I used floating point
- because the guy doesn't know what is going on at all with 3d, so better to
- look at only the math that is really happening. Besides, I still have to
- think to use fixed point. Whaddaya want for .5 hour programming.
-
- DIRECTIONS:
- ',' - rotates around the x axis
- '.' - rotates around the y axis
- '/' - rotates around the z axis
- 'q' - quits
-
- All rotations are done around global axes, not object axes.
- }
-
- uses
- graph,
- crt;
-
- const
- radtheta = 1 {degrees} * 3.1415926535 {radians} / 180 {per degrees};
- { sin and cos on computers are done in radians. }
-
- type
- tpointr = record { Just a record to hold 3d points }
- x, y, z : real;
- end;
-
- var
- box : array [0..7] of tpointr; { The box we will manipulate }
- c : char; { Our input mechanism }
-
- procedure init;
- var
- gd, gm : integer;
- { turns on graphics and creates a cube. Since the rotation routines
- rotate around the origin, I have centered the cube on the origin, so
- that it stays in place and only spins. }
- begin
- gd := detect;
- initgraph(gd, gm, 'e:\bp\bgi');
- box[0].x := -75; box[0].y := -75; box[0].z := -75;
- box[1].x := 75; box[1].y := -75; box[1].z := -75;
- box[2].x := 75; box[2].y := 75; box[2].z := -75;
- box[3].x := -75; box[3].y := 75; box[3].z := -75;
- box[4].x := -75; box[4].y := -75; box[4].z := 75;
- box[5].x := 75; box[5].y := -75; box[5].z := 75;
- box[6].x := 75; box[6].y := 75; box[6].z := 75;
- box[7].x := -75; box[7].y := 75; box[7].z := 75;
- end;
-
- procedure myline(x1, y1, z1, x2, y2, z2 : real);
- { Keeps the draw routine pretty. Pixels are integers, so I round. Since the
- cube is centered around 0,0 I move it over 200 to put it on screen. }
- begin
- { if you think those real mults are slow, here's some rounds too... hey, you
- may wonder, what happened to the stinking z coordinate? Ah, says I, this
- is the simplest of 3d viewing transforms. You just take the z coord out of
- things and boom. Looking straight down the z axis on the object. If I get
- inspired, I will add simple perspective transform to these. There, got
- inspired. Made mistakes. Foley et al are not very good at tutoring
- perspective and I'm kinda ready to be done and post this. }
- line(round(x1) + 200, round(y1) + 200, round(x2) + 200, round(y2) + 200);
- end;
-
- procedure draw;
- { my model is hard coded. No cool things like vertex and edge and face lists.}
- begin
- myline(box[0].x, box[0].y, box[0].z, box[1].x, box[1].y, box[1].z);
- myline(box[1].x, box[1].y, box[1].z, box[2].x, box[2].y, box[2].z);
- myline(box[2].x, box[2].y, box[2].z, box[3].x, box[3].y, box[3].z);
- myline(box[3].x, box[3].y, box[3].z, box[0].x, box[0].y, box[0].z);
-
- myline(box[4].x, box[4].y, box[4].z, box[5].x, box[5].y, box[5].z);
- myline(box[5].x, box[5].y, box[5].z, box[6].x, box[6].y, box[6].z);
- myline(box[6].x, box[6].y, box[6].z, box[7].x, box[7].y, box[7].z);
- myline(box[7].x, box[7].y, box[7].z, box[4].x, box[4].y, box[4].z);
-
- myline(box[0].x, box[0].y, box[0].z, box[4].x, box[4].y, box[4].z);
- myline(box[1].x, box[1].y, box[1].z, box[5].x, box[5].y, box[5].z);
- myline(box[2].x, box[2].y, box[2].z, box[6].x, box[6].y, box[6].z);
- myline(box[3].x, box[3].y, box[3].z, box[7].x, box[7].y, box[7].z);
-
- myline(box[0].x, box[0].y, box[0].z, box[5].x, box[5].y, box[5].z);
- myline(box[1].x, box[1].y, box[1].z, box[4].x, box[4].y, box[4].z);
- end;
-
- procedure rotx;
- {if you know your matrix multiplication, the following equations
- are derived from
-
- [x [ 1 0 0 0 [x',y',z',1]
- y 0 c -s 0 =
- z 0 s c 0
- 1] 0 0 0 1]
- }
- var
- i : integer;
- begin
- setcolor(0);
- draw;
- for i := 0 to 7 do
- begin
- box[i].x := box[i].x;
- box[i].y := box[i].y * cos(radTheta) + box[i].z * sin(radTheta);
- box[i].z := -box[i].y * sin(radTheta) + box[i].z * cos(radTheta);
- end;
- setcolor(15);
- draw;
- end;
-
- procedure roty;
- {if you know your matrix multiplication, the following equations
- are derived from
-
- [x [ c 0 s 0 [x',y',z',1]
- y 0 1 0 0 =
- z -s 0 c 0
- 1] 0 0 0 1]
- }
- var
- i : integer;
- begin
- setcolor(0);
- draw;
- for i := 0 to 7 do
- begin
- box[i].x := box[i].x * cos(radTheta) - box[i].z * sin(radTheta);
- box[i].y := box[i].y;
- box[i].z := box[i].x * sin(radTheta) + box[i].z * cos(radTheta);
- end;
- setcolor(15);
- draw;
- end;
-
- procedure rotz;
- {if you know your matrix multiplication, the following equations
- are derived from
-
- [x [ c -s 0 0 [x',y',z',1]
- y s c 0 0 =
- z 0 0 1 0
- 1] 0 0 0 1]
- }
- var
- i : integer;
- begin
- setcolor(0);
- draw;
- for i := 0 to 7 do
- begin
- box[i].x := box[i].x * cos(radTheta) + box[i].y * sin(radTheta);
- box[i].y := -box[i].x * sin(radTheta) + box[i].y * cos(radTheta);
- box[i].z := box[i].z;
- end;
- setcolor(15);
- draw;
- end;
-
-
- begin
- init;
- setcolor(14);
- draw;
- repeat
- c := readkey;
- case c of
- ',' : rotx;
- '.' : roty;
- '/' : rotz;
- else {who gives a};
- end; {case}
- until c = 'q';
- closegraph;
- end.
-
-